﻿using System;
using System.Collections.Generic;
using System.Linq;
using XcoAppSpaces.Contracts.Messaging;

namespace XcoAppSpaces.Core.CcrWiring.CcrRemote
{
	///// <summary>
	///// Base class for special Ccr tasks that can send data to a remote worker or port instance.
	///// </summary>
	//abstract class RemotableTask : TaskCommon, IRemotableTask
	//{
	//	protected readonly Handler<MessageToSend> messageProcessor;
	//	protected readonly IPort assignedPort;
	//	public string RemoteAddress { get; private set; }
	//	public string CommServiceName { get; private set; }
	//	public Guid PortGuid { get; private set; }
	//	public MessageTransferMode Mode { get; private set; }
		
	//	private IPortElement executionParameter;

	//	protected RemotableTask(Handler<MessageToSend> messageProcessor, string remoteAddress, string commServiceName, Guid portGuid, IPort assignedPort, MessageTransferMode mode)
	//	{
	//		this.messageProcessor = messageProcessor;
	//		this.RemoteAddress = remoteAddress;
	//		this.CommServiceName = commServiceName;
	//		this.PortGuid = portGuid;
	//		this.assignedPort = assignedPort;
	//		this.Mode = mode;
	//	}

	//	internal Receiver CreateReceiver(IPort port, MessageTransferMode transferMode)
	//	{
	//		return new Receiver((transferMode == MessageTransferMode.Parallel), (IPortReceive)port, PartialClone(port, transferMode));
	//	}

	//	public override IEnumerator<ITask> Execute()
	//	{
	//		ProcessItem(this.executionParameter.Item);
	//		return null;
	//	}

	//	public override IPortElement this[int index]
	//	{
	//		get
	//		{
	//			if (index != 0)
	//				throw new ArgumentException("parameter out of range", "index");
	//			return this.executionParameter;
	//		}
	//		set
	//		{
	//			if (index != 0)
	//				throw new ArgumentException("parameter out of range", "index");
	//			this.executionParameter = value;
	//		}
	//	}

	//	public override int PortElementCount
	//	{
	//		get { return 1; }
	//	}

	//	public void Send(object item, Port<Exception> commErrorPort, IPort commAckPort)
	//	{
	//		if (!(commAckPort is Port<Ack>))
	//			throw new ArgumentException("Port must be of type Port<Ack>!", "commAckPort");
	//		messageProcessor(new MessageToSend(RemoteAddress, CommServiceName, GetCausalityContext(), CreateMessage(item), commErrorPort, (Port<Ack>)commAckPort));
	//	}

	//	private void ProcessItem(object item)
	//	{
	//		try
	//		{
	//			messageProcessor(new MessageToSend(RemoteAddress, CommServiceName, GetCausalityContext(), CreateMessage(item), null, null));
	//		}
	//		finally
	//		{
	//			if (this.Mode == MessageTransferMode.Sequential)
	//			{
	//				//re-register task at port because sequential processing is done through non-persistent tasks
	//				assignedPort.ReceiveWithRemotableTask(this.TaskQueue, this);
	//			}
	//		}
	//	}

	//	private static CausalityContext GetCausalityContext()
	//	{
	//		var causalities = Dispatcher.ActiveCausalities.Select(c => new CausalityInfo(c)).ToArray();
	//		return (causalities.Length > 0 ? new CausalityContext(causalities) : null);
	//	}

	//	/// <summary>
	//	/// Method that must be implemented by base classes to create a message
	//	/// that should be sent from an item that has been posted to the port
	//	/// where this task is registered.
	//	/// </summary>
	//	/// <param name="value">The item that has been posted.</param>
	//	/// <returns>The message that should be sent.</returns>
	//	protected abstract RemoteMessage CreateMessage(object value);

	//	/// <summary>
	//	/// Partially clones the task, while using the given port and transfer mode.
	//	/// </summary>
	//	/// <param name="assignedPort"></param>
	//	/// <param name="mode"></param>
	//	/// <returns></returns>
	//	public abstract RemotableTask PartialClone(IPort assignedPort, MessageTransferMode mode);
	//}
}
